package web;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;

import org.primefaces.model.DualListModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import service.ManutencaoService;
import service.PapelUsuarioService;
import service.PessoaService;
import service.UsuarioService;
import util.UtilColecao;
import entity.PapelUsuario;
import entity.Pessoa;
import entity.PessoaFisica;
import entity.PessoaJuridica;
import entity.Usuario;
import enumeration.GeneroEnum;
import enumeration.TipoPessoaEnum;

@Controller
@Scope("view")
public class ManterPessoaMB extends ManutencaoCRUDBean<Pessoa> implements
		Serializable {

	private static final long serialVersionUID = 2980992478110115218L;

	@Autowired
	private PessoaService pessoaService;
	@Autowired
	private UsuarioService usuarioService;
	@Autowired
	private PapelUsuarioService papelUsuarioService;

	private Pessoa pessoa;
	private PessoaFisica pessoaFisica;
	private PessoaJuridica pessoaJuridica;
	private Usuario usuario;
	private TipoPessoaEnum tipoPessoaEnum;

	private List<SelectItem> tipoPessoasSelectItens;
	private List<SelectItem> generosSelectItens;

	private boolean vincularUsuario;

	private DualListModel<PapelUsuario> papeisDualList;

	private List<PapelUsuario> listaPapeis;

	public void alterarTipoPessoa() {
		switch (tipoPessoaEnum) {
		case FISICA:
			pessoa = pessoaFisica;
			break;
		case JURIDICA:
			pessoa = pessoaJuridica;
			break;
		}
	}

	@Override
	protected void prepararAdicionar() {

		vincularUsuario = false;

		pessoaFisica = pessoaService.criarNovaPessoaFisica();
		pessoaJuridica = pessoaService.criarNovaPessoaJuridica();
		pessoa = pessoaFisica;

		tipoPessoaEnum = TipoPessoaEnum.FISICA;

		carregarComboTipoPessoa();
		carregarComboGenero();
	}

	private void carregarComboGenero() {
		generosSelectItens = criarListSelectItem();

		for (GeneroEnum generoEnum : GeneroEnum.values()) {
			generosSelectItens.add(new SelectItem(generoEnum, generoEnum
					.getDescricao()));
		}
	}

	private void carregarComboTipoPessoa() {
		tipoPessoasSelectItens = criarListSelectItem();

		for (TipoPessoaEnum tipoPessoaEnum : TipoPessoaEnum.values()) {
			tipoPessoasSelectItens.add(new SelectItem(tipoPessoaEnum,
					tipoPessoaEnum.getDescricao()));
		}
	}

	public void doPrepararUsuario() {
		if (vincularUsuario) {

			usuario = new Usuario();
			carragerListaPapeis();
			papeisDualList = new DualListModel<PapelUsuario>(listaPapeis,
					new ArrayList<PapelUsuario>());
		}
	}

	private void carragerListaPapeis() {
		listaPapeis = papelUsuarioService.listarAtivos();
	}

	private List<SelectItem> criarListSelectItem() {
		return new ArrayList<SelectItem>();
	}

	@Override
	public void doSalvarAction() {

		if (vincularUsuario) {
			usuario.setListaPapeisUsuario(papeisDualList.getTarget());
			usuario.setPessoa(pessoa);
			pessoaService.salvarComUsuario(pessoa, usuario);
			doPesquisarAction();
			inicializar();

		} else {
			if (pessoa.getId() == null) {
				super.doSalvarAction();
			} else {
				pessoaService.salvarComUsuario(pessoa, null);
				doPesquisarAction();
				inicializar();
			}
		}
	}

	@Override
	public void doDetalharAction() {
		if (getEntidade() instanceof PessoaFisica) {
			tipoPessoaEnum = TipoPessoaEnum.FISICA;
		} else {
			tipoPessoaEnum = TipoPessoaEnum.JURIDICA;
		}

		usuario = usuarioService.buscarPorPessoa(getEntidade());
		super.doDetalharAction();
	}

	@Override
	public void doEditarAction() {
		super.doEditarAction();
		usuario = usuarioService.buscarPorPessoa(getEntidade());
		carregarComboTipoPessoa();
		carregarComboGenero();

		if (usuario == null) {
			vincularUsuario = false;
		} else {
			vincularUsuario = true;

			carragerListaPapeis();
			if (!UtilColecao.isColecaoVazia(usuario.getListaPapeisUsuario())) {
				final List<PapelUsuario> papeisDisponiveis = new ArrayList<PapelUsuario>();

				for (PapelUsuario papelUsuario : listaPapeis) {
					if (!usuario.getListaPapeisUsuario().contains(papelUsuario)) {
						papeisDisponiveis.add(papelUsuario);
					}
				}
				papeisDualList = new DualListModel<PapelUsuario>(
						papeisDisponiveis, usuario.getListaPapeisUsuario());
			} else {
				papeisDualList = new DualListModel<PapelUsuario>(listaPapeis,
						new ArrayList<PapelUsuario>());
			}
		}
	}

	@Override
	public ManutencaoService<Pessoa> getService() {
		return pessoaService;
	}

	@Override
	public Pessoa getEntidade() {
		return pessoa;
	}

	@Override
	public void setEntidade(Pessoa entidade) {
		pessoa = entidade;
	}

	public List<SelectItem> getTipoPessoasSelectItens() {
		return tipoPessoasSelectItens;
	}

	public TipoPessoaEnum getTipoPessoaEnum() {
		return tipoPessoaEnum;
	}

	public void setTipoPessoaEnum(TipoPessoaEnum tipoPessoaEnum) {
		this.tipoPessoaEnum = tipoPessoaEnum;
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public boolean isVincularUsuario() {
		return vincularUsuario;
	}

	public void setVincularUsuario(boolean vincularUsuario) {
		this.vincularUsuario = vincularUsuario;
	}

	public boolean isPessoaJuridica() {
		return tipoPessoaEnum.equals(TipoPessoaEnum.JURIDICA);
	}

	public boolean isPessoaFisica() {
		return tipoPessoaEnum.equals(TipoPessoaEnum.FISICA);
	}

	public List<SelectItem> getGenerosSelectItens() {
		return generosSelectItens;
	}

	public DualListModel<PapelUsuario> getPapeisDualList() {
		return papeisDualList;
	}

	public void setPapeisDualList(DualListModel<PapelUsuario> papeisDualList) {
		this.papeisDualList = papeisDualList;
	}

}
